每天的專案會同步到 GitLab 上,可以前往 GitLab 查看。
有興趣的朋友歡迎留言 or 來信討論,我的信箱是 nickchen1998@gmail.com。
因為 Pinecone 免費版只能建立一組索引庫,為了避免每次效果混淆,每次都會把資料清除後再重新建立索引庫。
PDF 作為一班企業做常使用的文件檔,LangChain 當然也有協助我們包好可以使用的 Loader,這次的範例當中我們會使用 勞動基準法 來作為範例展示。
下面的範例是使用 pymupdf 以頁為單位截取出內容的範例:
pip install pymupdf
from pprint import pprint
from env_settings import BASE_DIR
from langchain_community.document_loaders import PyMuPDFLoader
loader = PyMuPDFLoader(file_path=BASE_DIR / "勞動基準法.pdf")
pprint(loader.load())
可以看到 LangChain 不僅協助我們把 PDF 的內容以及 metadata 讀取出來,也同時協助我們轉換成寫入用的 Document 物件了!
話不多說,我們馬上使用第八天的方式來把剛剛讀取出來的 Document 物件寫入向量庫:
from env_settings import EnvSettings, BASE_DIR
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone
loader = PyMuPDFLoader(file_path=BASE_DIR / "勞動基準法.pdf")
# 寫入向量
env_settings = EnvSettings()
embedding = OpenAIEmbeddings(
openai_api_key=env_settings.OPENAI_API_KEY
)
vector_store = PineconeVectorStore(
index=Pinecone(api_key=env_settings.PINECONE_API_KEY).Index("ithelp"),
embedding=embedding
)
vector_store.add_documents(loader.load())
可以看到下圖中,我們成功將 metadata 以及 text 寫入向量資料庫當中:
接著讓我們使用下面的程式碼來試著查詢一下:
from env_settings import EnvSettings, BASE_DIR
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone
loader = PyMuPDFLoader(file_path=BASE_DIR / "勞動基準法.pdf")
# 寫入向量
env_settings = EnvSettings()
embedding = OpenAIEmbeddings(
openai_api_key=env_settings.OPENAI_API_KEY
)
vector_store = PineconeVectorStore(
index=Pinecone(api_key=env_settings.PINECONE_API_KEY).Index("ithelp"),
embedding=embedding
)
res = vector_store.similarity_search(
"勞工滿一年會有幾天特休?",
k=1
)
print(res[0].page_content)
下圖中可以看到我們搜尋出來的結果:
在拿到搜尋結果之後,我們可以使用下面的程式碼來將搜尋結果以及問題串接起來:
from env_settings import EnvSettings
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone
# 建立 Vector 物件處理向量
env_settings = EnvSettings()
vector_store = PineconeVectorStore(
index=Pinecone(api_key=env_settings.PINECONE_API_KEY).Index("ithelp"),
embedding=OpenAIEmbeddings(
openai_api_key=env_settings.OPENAI_API_KEY
)
)
# 依靠問題查出相關段落
question = "勞工工作滿一年有幾天特休?"
documents = vector_store.similarity_search(question, k=1)
# 建立 chain 並回答問題
prompt = ChatPromptTemplate.from_template(
"""
原始問題: {question}
取得的參考資料: {data}
""",
)
llm = ChatOpenAI(
api_key=env_settings.OPENAI_API_KEY,
model_name="gpt-4o"
)
chain = prompt | llm
result = chain.invoke({"question": question, "data": documents[0].page_content})
print(result.content)
下圖結果為 GPT 協助我們依照找出的段落彙整出的答案:
今天我們實際串接了一次 RAG 的基本流程給大家看,明天我們會介紹資料型態的檔案該如何進行處理,會以 JSON 格式為範例,有興趣的朋友可以提前準備一份資料!